home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / cit.arc / CONFG.C < prev    next >
Encoding:
C/C++ Source or Header  |  1985-12-26  |  38.0 KB  |  1,177 lines

  1. /************************************************************************/
  2. /*                confg.c                 */
  3. /*    configuration program for Citadel bulletin board system.    */
  4. /************************************************************************/
  5.  
  6. #include "ctdl.h"
  7.  
  8. /************************************************************************/
  9. /*                History                 */
  10. /*                                    */
  11. /* 85Dec26 HAW    Add CALL-LOG define.                    */
  12. /* 85Nov15 HAW    MS-DOS library update.                    */
  13. /* 85Oct27 HAW    Kill CERMETEK.                        */
  14. /* 85Oct17 HAW    Add paramVers, change bauds to array, searchBaud chg.    */
  15. /* 85Oct16 HAW    Kill CLOCK, add officeStuff.                */
  16. /* 85Aug24 HAW    Add duomessage file, NETDISK specification.        */
  17. /* 85Jul07 HAW    Update so won't go through total recon. on init.    */
  18. /* 85May27 HAW    Start stuffing in auto-networking stuff.        */
  19. /* 85May22 HAW    Start conversion to make log file size sysop selectable.*/
  20. /* 85May11 HAW    Make "Lobby" sysop definable                */
  21. /* 85May06 HAW    Add bail out code.                    */
  22. /* 85May05 HAW    Add helpDisk parameter for 3 disk system.        */
  23. /* 85Apr10 HAW    Fix logSort, alphabetize file.                */
  24. /* 85Mar11 HAW    Put all user functions in this file.            */
  25. /* 85Feb18 HAW    Add baud search stuff.                    */
  26. /* 85Jan20 HAW    Use MSDOS #define for date stuff.            */
  27. /* 84Sep05 HAW    Isolate strangeness in compiler's library.  See note.    */
  28. /* 84Aug30 HAW    Onwards to MS-DOS!                    */
  29. /* 84Apr08 HAW    Update to BDS C 1.50a begun.                */
  30. /* 82Nov20 CrT    Created.                        */
  31. /************************************************************************/
  32.  
  33. /************************************************************************/
  34. /*                Contents                */
  35. /*                                    */
  36. /*    dGetWord()        reads a word off disk            */
  37. /*    init()            system startup initialization        */
  38. /*    main()            main controller             */
  39. /*    illegal()        abort bottleneck            */
  40. /*    getMessage()        load message into RAM            */
  41. /*    getMsgChar()        returns successive chars off disk    */
  42. /*    getMsgStr()        reads a string out of message.buf    */
  43. /*    msgInit()        sets up cfg.catChar, catSect etc.    */
  44. /*    startAt()        setup to read a message off disk    */
  45. /*    unGetMsgChar()        return a char to getMsgChar()        */
  46. /*    zapMsgFile()        initialize ctdlmsg.sys            */
  47. /*    realZap()        does work of zapMsgFile()        */
  48. /*    indexRooms()        build RAM index to ctdlroom.sys     */
  49. /*    noteRoom()        enter room into RAM index        */
  50. /*    zapRoomFile()        erase & re-initialize ctdlroom.sys    */
  51. /*    setSpace()        set default disk and user#        */
  52. /*    hash()            hashes a string to an integer        */
  53. /*    logInit()        builds the RAM index to CTDLLOG.SYS    */
  54. /*    noteLog()        enters a userlog record into RAM index    */
  55. /*    sortLog()        sort CTDLLOG by time since last call    */
  56. /*    wrapup()        finishes and writes ctdlTabl.sys    */
  57. /*    zapLogFile()        erases & re-initializes CTDLLOG.SYS    */
  58. /************************************************************************/
  59.  
  60. /************************************************************************/
  61. /*                Strangenesses    (Hue, Jr., 12Sep84)    */
  62. /*    Have discovered that the line:                    */
  63. /*    sscanf(line, "\"%s\"", str);                    */
  64. /*    is not parsed the same way by this compiler as it is by BDS;    */
  65. /*    this is highly unfortunate and excrable.  So, all porters    */
  66. /*    should note that scanf() is not, in any way, "portable."  If    */
  67. /*    BDS is "non-standard", then the standard sucks.         */
  68. /************************************************************************/
  69.  
  70. /************************************************************************/
  71. /*          External variable declarations in CONFG.C        */
  72. /************************************************************************/
  73. extern struct config cfg;    /* The configuration variable        */
  74. static unsigned char GMCCache;    /* To unGetMsgChar() into        */
  75. struct msgB         msgBuf;    /* The -sole- message buffer        */
  76. extern struct netBuffer     netBuf;
  77. FILE             *msgfl;    /* file descriptor for the msg file    */
  78. static int   thisChar;        /* next char in sectBuf         */
  79. static unsigned thisSector;    /* next sector in msgfl         */
  80. static int   oldChar;        /* Old value of thisChar        */
  81. static unsigned oldSector;    /* Old value of thisSector        */
  82. static unsigned char  sectBuf[SECTSIZE];
  83.                    /* ^ msgfl sector buffer (simulated)    */
  84. extern struct rTable roomTab[MAXROOMS]; /* RAM index of rooms        */
  85. extern struct aRoom  roomBuf;        /* room buffer            */
  86. extern FILE     *roomfl;        /* file descriptor for rooms    */
  87. extern int    thisRoom;      /* room currently in roomBuf      */
  88. extern struct logBuffer logBuf;     /* Log buffer of a person    */
  89. extern struct lTable   *logTab;     /* RAM index of pippuls     */
  90. extern int     thisLog;        /* entry currently in logBuf    */
  91. extern FILE      *logfl;        /* log file descriptor        */
  92. extern FILE      *netfl;
  93. char     *baseRoom;
  94. extern struct netTable *netTab;
  95. extern int     thisNet;
  96. long        mailCount=0;
  97. char  msgZap =    FALSE,
  98.       logZap =    FALSE,
  99.       roomZap = FALSE;
  100.  
  101.  
  102. /************************************************************************/
  103. /*        External function definitions for CONFG.C        */
  104. /************************************************************************/
  105. extern FILE   *fopen();
  106. char          toUpper();
  107. unsigned char getMsgChar();
  108. int          fread();
  109. long          fseek();
  110. char          *malloc();
  111.  
  112. /************************************************************************/
  113. /*    init() -- master system initialization                */
  114. /************************************************************************/
  115. init(attended)
  116. int attended;
  117. {
  118.     unsigned char c;
  119.     unsigned      i;
  120.     char      *msgFile, *netFile, *roomFile, *logFile;
  121.  
  122.     cfg.sizeLTentry = sizeof(*logTab);
  123.  
  124.     cfg.debug        = FALSE;
  125.     cfg.noChat        = TRUE;
  126.  
  127.     /* shave-and-a-haircut/two bits pause pattern for ringing sysop: */
  128.     cfg.shave[0]    = 40;
  129.     cfg.shave[1]    = 20;
  130.     cfg.shave[2]    = 20;
  131.     cfg.shave[3]    = 40;
  132.     cfg.shave[4]    = 80;
  133.     cfg.shave[5]    = 40;
  134.     cfg.shave[6]    =250;
  135.  
  136.     /* initialize input character-translation table:    */
  137.     for (c = 0;  c < '\40';  c++) {
  138.     cfg.filter[c] = '\0';        /* control chars -> nulls    */
  139.     }
  140.     for (c='\40'; c < 128;   c++) {
  141.     cfg.filter[c] = c;        /* pass printing chars        */
  142.     }
  143.     cfg.filter[SPECIAL]     = SPECIAL;
  144.     cfg.filter[CNTRLl]        = CNTRLl;
  145.     cfg.filter[DEL    ]   = BACKSPACE;
  146.     cfg.filter[BACKSPACE]   = BACKSPACE;
  147.     cfg.filter[XOFF    ]   = 'P'      ;
  148.     cfg.filter['\r'    ]   = NEWLINE  ;
  149.     cfg.filter[CNTRLO    ]   = 'N'      ;
  150.  
  151.     setSpace(cfg.homeDisk, "");
  152.  
  153.     msgFile    = "a:ctdlmsg.sys";
  154.     *msgFile   += cfg.msgDisk;
  155.     netFile    = "a:ctdlnet.sys";
  156.     *netFile   += cfg.netDisk;
  157.     roomFile    = "a:ctdlroom.sys";
  158.     *roomFile  += cfg.sysDisk;
  159.     logFile    = "a:ctdllog.sys";
  160.     *logFile   += cfg.sysDisk;
  161.  
  162.     /* open message file */
  163.     if ((netfl = fopen(netFile, "rb")) == NULL) {
  164.     printf(" %s not found, creating new file.\n", netFile);
  165.     if ((netfl = fopen(netFile, "wb")) == NULL)
  166.         illegal("?Can't create the net file!");
  167.     }
  168.  
  169.     if ((msgfl = fopen(msgFile, "rwb")) == NULL) {
  170.     if (!attended)
  171.         illegal("!System must be attended for creation!");
  172.     printf(" %s not found, creating new file. \n", msgFile);
  173.     if ((msgfl = fopen(msgFile, "wrb")) == NULL)
  174.         illegal("?Can't create the message file!");
  175.     printf(" (Be sure to initialize it!)\n");
  176.     }
  177.  
  178.     /* open room file */
  179.     if ((roomfl = fopen(roomFile, "rwb")) == NULL) {
  180.     if (!attended)
  181.         illegal("!System must be attended for creation!");
  182.     printf(" %s not found, creating new file. \n", roomFile);
  183.     if ((roomfl = fopen(roomFile, "wrb")) == NULL)
  184.        illegal("?Can't create room file!");
  185.     printf(" (Be sure to initialize it!)\n");
  186.     }
  187.  
  188.     /* open userlog file */
  189.     if ((logfl = fopen(logFile, "rwb")) == NULL) {
  190.     if (!attended)
  191.         illegal("!System must be attended for creation!");
  192.     printf(" %s not found, creating new file. \n", logFile);
  193.     if ((logfl = fopen(logFile, "wrb")) == NULL)
  194.         illegal("?Can't create log file!");
  195.     printf(" (Be sure to initialize it!)\n");
  196.     }
  197.  
  198.     printf("\n Erase and initialize log, message and/or room files?");
  199.     if (attended)
  200.     if (toUpper(getch()) == 'Y') {
  201.         /* each of these has an additional go/no-go interrogation: */
  202.         msgZap  = zapMsgFile();
  203.         roomZap = zapRoomFile();
  204.         logZap  = zapLogFile();
  205.     }
  206. }
  207.  
  208. /************************************************************************/
  209. /*    main() for confg.c                        */
  210. /************************************************************************/
  211. main(argc, argv)
  212. int  argc;
  213. char **argv;
  214. {
  215.     FILE *fBuf;
  216.     char line[90];
  217.     char cmd[90], var[90], string[90];
  218.     int  arg, arg2, args;
  219.     int  i, j, offset = 0;
  220.     union {
  221.     int          *pi;
  222.     unsigned char *pc;
  223.     } nextCode;     /* where to deposit next code */
  224.  
  225.     cfg.paramVers = 2;
  226.     cfg.weAre      = CONFIGUR;
  227.     cfg.MAXLOGTAB = 0;        /* Initialize, just in case        */
  228.     if ((fBuf = fopen("ctdlcnfg.sys", "r")) == NULL) {    /* ASCII mode    */
  229.     printf("?Can't find ctdlCnfg.sys!\n");
  230.     exit();
  231.     }
  232.     nextCode.pc = &cfg.codeBuf[0];
  233.     while (fgets(line, 90, fBuf) != NULL) {
  234.     if (args = sscanf(line, "%s %s %x ", cmd, var, &arg)) {
  235.         if    (strCmp(cmd, "#define" ) == SAMESTRING    &&  args == 3) {
  236.         printf("#define '%s' as %x\n", var, arg);
  237.                if (strCmp(var, "MEGAHZ"    )    == SAMESTRING) {
  238.             cfg.megaHz        = arg;
  239.         } else if (strCmp(var, "CRYPTSEED" )    == SAMESTRING) {
  240.             cfg.cryptSeed   = arg;
  241. #ifndef MSDOS
  242.         } else if (strCmp(var, "CLOCK"       )    == SAMESTRING) {
  243.             cfg.clock        = arg;
  244. #endif
  245.         } else if (strCmp(var, "MESSAGEK"  )    == SAMESTRING) {
  246.                 cfg.maxMSector  = arg*8;
  247.         } else if (strCmp(var, "MSGDISK"   )    == SAMESTRING) {
  248.             cfg.msgDisk     = arg;
  249.         } else if (strCmp(var, "HOMEDISK"  )    == SAMESTRING) {
  250.             cfg.homeDisk    = arg;
  251.         } else if (strCmp(var, "SYSDISK"   )    == SAMESTRING) {
  252.             cfg.sysDisk     = arg;
  253.         } else if (strCmp(var, "NETDISK"   )    == SAMESTRING) {
  254.             cfg.netDisk     = arg;
  255.         } else if (strCmp(var, "LOGINOK"   )    == SAMESTRING) {
  256.             cfg.unlogLoginOk= arg;
  257.         } else if (strCmp(var, "ENTEROK"   )    == SAMESTRING) {
  258.             cfg.unlogEnterOk= arg;
  259.         } else if (strCmp(var, "READOK"    )    == SAMESTRING) {
  260.             cfg.unlogReadOk = arg;
  261.         } else if (strCmp(var, "ROOMOK"    )    == SAMESTRING) {
  262.             cfg.nonAideRoomOk=arg;
  263.         } else if (strCmp(var, "ALLMAIL"   )    == SAMESTRING) {
  264.             cfg.noMail        = !arg;
  265.         } else if (strCmp(var, "SEARCHBAUD")    == SAMESTRING) {
  266.             cfg.search_baud = arg;
  267.         } else if (strCmp(var, "IBM"       )    == SAMESTRING) {
  268.             cfg.IBM_or_clone= arg;
  269.         } else if (strCmp(var, "TIMEOUT"   )    == SAMESTRING) {
  270.             cfg.dailyTimeout= arg;
  271.         } else if (strCmp(var, "HOUROUT"   )    == SAMESTRING) {
  272.             if ((cfg.hourOut     = arg) > 23 || arg < 0)
  273.             illegal("Illegal value: 0 <= HOUROUT <= 23");
  274.         } else if (strCmp(var, "MIRRORMSG" )    == SAMESTRING) {
  275.             cfg.mirror = arg;
  276.         } else if (strCmp(var, "MSG2DISK"  )    == SAMESTRING) {
  277.             cfg.mbkpDisk = arg;
  278.         } else if (strCmp(var, "LOGSIZE"   )    == SAMESTRING) {
  279.             cfg.MAXLOGTAB   = arg;
  280.             logTab = (struct lTable *) malloc(sizeof(*logTab) * arg);
  281.         } else if (strCmp(var, "NETWORK"   )    == SAMESTRING) {
  282.             cfg.netParticipant = arg;
  283.         } else if (strCmp(var, "LONG-HAUL" )    == SAMESTRING) {
  284.             cfg.longHaul = arg;
  285.         } else if (strCmp(var, "DAYDIV"    )    == SAMESTRING) {
  286.             cfg.dayDiv = arg;
  287.         } else if (strCmp(var, "NETHOUR"   )    == SAMESTRING) {
  288.             cfg.netHour = arg;
  289.         } else if (strCmp(var, "NETLENGTH" )    == SAMESTRING) {
  290.             cfg.netLength = arg;
  291.         } else if (strCmp(var, "SYSBAUD"   )    == SAMESTRING) {
  292.             cfg.sysBaud   = arg;
  293.             if (arg > 2 || arg < 0)
  294.             illegal(
  295. "Invalid SYSBAUD value -- only 0=300, 1=3/12, 2=3/12/24 are valid!");
  296.         } else if (strCmp(var, "CALL-LOG"  )    == SAMESTRING) {
  297.             cfg.call_log  = arg;
  298.         } else {
  299.             printf("? -- no variable '%s' known! -- ignored.\n", var);
  300.         }
  301.  
  302.         } else if (strCmp(cmd, "#start"  ) == SAMESTRING) {
  303.         printf("#start procedure '%s'\n", var);
  304.         if      (strCmp(var, "HANGUP"    ) == SAMESTRING) {
  305.             cfg.pHangUp     = offset;
  306.         } else if (strCmp(var, "INITPORT"  ) == SAMESTRING) {
  307.             cfg.pInitPort   = offset;
  308.         } else if (strCmp(var, "CARRDETECT") == SAMESTRING) {
  309.             cfg.pCarrDetect = offset;
  310.         } else if (strCmp(var, "MIREADY"   ) == SAMESTRING) {
  311.             cfg.pMIReady    = offset;
  312.         } else if (strCmp(var, "MOREADY"   ) == SAMESTRING) {
  313.             cfg.pMOReady    = offset;
  314.         } else if (strCmp(var, "SET300"    ) == SAMESTRING) {
  315.             cfg.pBauds[ONLY_300] = offset;
  316.         } else if (strCmp(var, "SET1200"   ) == SAMESTRING) {
  317.             cfg.pBauds[BOTH_300_1200] = offset;
  318.         } else if (strCmp(var, "SET2400"   ) == SAMESTRING) {
  319.             cfg.pBauds[TH_3_12_24] = offset;
  320.         } else if (strCmp(var, "CHECKBAUD" ) == SAMESTRING) {
  321.             cfg.pCheckBaud  = offset;
  322. #ifndef MSDOS
  323.         } else if (strCmp(var, "INITDATE"  ) == SAMESTRING) {
  324.             cfg.pInitDate   = offset;
  325.         } else if (strCmp(var, "GETDAY"    ) == SAMESTRING) {
  326.             cfg.pGetDay     = offset;
  327.         } else if (strCmp(var, "GETMONTH"  ) == SAMESTRING) {
  328.             cfg.pGetMonth   = offset;
  329.         } else if (strCmp(var, "GETYEAR"   ) == SAMESTRING) {
  330.             cfg.pGetYear    = offset;
  331. #endif
  332.         } else printf("?--no procedure '%s' known!\n", var);
  333.  
  334.         } else if (strCmp(cmd, "#code"   ) == SAMESTRING) {
  335.         printf("#code '%s'\n", var);
  336.         if      (strCmp(var, "LOAD"       ) == SAMESTRING) {
  337.             *nextCode.pc++    = LOAD;
  338.             *nextCode.pi++    = arg;
  339.             offset += 3;
  340.         } else if (strCmp(var, "ANDI"       ) == SAMESTRING) {
  341.             *nextCode.pc++    = ANDI;
  342.             *nextCode.pc++    = arg;
  343.             offset += 2;
  344.         } else if (strCmp(var, "ORI"       ) == SAMESTRING) {
  345.             *nextCode.pc++    = ORI;
  346.             *nextCode.pc++    =arg;
  347.             offset += 2;
  348.         } else if (strCmp(var, "XORI"       ) == SAMESTRING) {
  349.             *nextCode.pc++    = XORI;
  350.             *nextCode.pc++    = arg;
  351.             offset += 2;
  352.         } else if (strCmp(var, "STORE"       ) == SAMESTRING) {
  353.             *nextCode.pc++    = STORE;
  354.             *nextCode.pi++    = arg;
  355.             offset += 3;
  356.         } else if (strCmp(var, "LOADI"       ) == SAMESTRING) {
  357.             *nextCode.pc++    = LOADI;
  358.             *nextCode.pc++    = arg;
  359.             offset += 2;
  360.         } else if (strCmp(var, "RET"       ) == SAMESTRING) {
  361.             *nextCode.pc++    = RET;
  362.             offset++;
  363.         } else if (strCmp(var, "INP"       ) == SAMESTRING) {
  364.             *nextCode.pc++    = INP;
  365.             *nextCode.pi++    = arg;
  366.             offset += 3;
  367.         } else if (strCmp(var, "OUTP"       ) == SAMESTRING) {
  368.             *nextCode.pc++    = OUTP;
  369.             *nextCode.pi++    = arg;
  370.             offset += 3;
  371.         } else if (strCmp(var, "PAUSEI"    ) == SAMESTRING) {
  372.             *nextCode.pc++    = PAUSEI;
  373.             *nextCode.pc++    = arg;
  374.             offset += 2;
  375.         } else if (strCmp(var, "ARRAY[]="  ) == SAMESTRING) {
  376.             *nextCode.pc++    = STOREX;
  377.             *nextCode.pc++    = arg;
  378.             offset += 2;
  379.         } else if (strCmp(var, "ARRAY[]"   ) == SAMESTRING) {
  380.             *nextCode.pc++    = LOADX;
  381.             *nextCode.pc++    = arg;
  382.             offset += 2;
  383.         } else if (strCmp(var, "OPR#"       ) == SAMESTRING) {
  384.             *nextCode.pc++    = OPRNUMBER;
  385.             offset++;
  386.  
  387.             /* reparse to pick up string: */
  388.             sscanf(line, "%s %s \"%s\" %d %d",
  389.             cmd, var, string, &arg, &arg2
  390.             );
  391.          /* BDS was excellent.  C86 sucks.    Reparse by hand <sigh>: */
  392.             for (i = strLen(line) - 1; line[i] != '"'; i--)
  393.             ;
  394.             sscanf(line + ++i, " %d %d", &arg, &arg2);
  395.  
  396.             string[strLen(string) - 1] = '\0';    /* Bug kludge    */
  397.             /* copy string into code buffer: */
  398.             strCpy(nextCode.pc, string);
  399.             while (*nextCode.pc++)    /* step over string    */
  400.             offset++;
  401.             offset++;
  402.             *nextCode.pc++    = arg;    /* lower limit        */
  403.             *nextCode.pc++    = arg2; /* upper limit        */
  404.             offset += 2;
  405.         } else if (strCmp(var, "OUTSTRING" ) == SAMESTRING) {
  406.             *nextCode.pc++    = OUTSTRING;
  407.             offset++;
  408.             /* reparse to pick up string: */
  409. /*            sscanf(line, "%s %s \"%s\"", cmd, var, string);    */
  410. /* Reparse on our own (stupid scanf() function, it worked in BDS!): */
  411.                     readString(line, nextCode.pc);
  412.             while (*nextCode.pc++)    /* step over string    */
  413.             offset++;
  414.             offset++;
  415.             nextCode.pc--;
  416.             *nextCode.pc++    = '\r'; /* add a CR        */
  417.             *nextCode.pc++    = '\0'; /* tie off with null    */
  418.             offset++;
  419.         } else printf("?--no code '%s'!\n", var);
  420.  
  421.         } else if (strCmp(cmd, "#nodeTitle") == SAMESTRING) {
  422.             readString(line, nextCode.pc);
  423.             cfg.nodeTitle   = offset;
  424.             while (*nextCode.pc++)    /* step over string    */
  425.             offset++;
  426.             offset++;         /* I don't know why, but it works    */
  427.  
  428.         } else if (strCmp(cmd, "#officeStuff") == SAMESTRING) {
  429.             readString(line, nextCode.pc);
  430.             cfg.officeStuff = offset;
  431.             while (*nextCode.pc++)    /* step over string    */
  432.             offset++;
  433.             offset++;         /* I don't know why, but it works    */
  434.  
  435.         } else if (strCmp(cmd, "#nodeName" ) == SAMESTRING) {
  436.             readString(line, nextCode.pc);
  437.             if (strLen(nextCode.pc) > 19)
  438.             illegal("nodeName too long; must be less than 20");
  439.             cfg.nodeName    = offset;
  440.             while (*nextCode.pc++)    /* step over string    */
  441.             offset++;
  442.             offset++;         /* I don't know why, but it works    */
  443.         } else if (strCmp(cmd, "#nodeId"   ) == SAMESTRING) {
  444.             readString(line, nextCode.pc);
  445.             if (strLen(nextCode.pc) > 19)
  446.             illegal("nodeId too long; must be less than 20");
  447.             cfg.nodeId        = offset;
  448.             while (*nextCode.pc++)    /* step over string    */
  449.             offset++;
  450.             offset++;         /* I don't know why, but it works    */
  451.             } else if (strCmp(cmd, "#baseRoom") == SAMESTRING) {
  452.             readString(line, nextCode.pc);
  453.             if (strLen(nextCode.pc) > 19)
  454.             illegal("baseRoom too long; must be less than 20");
  455.             cfg.bRoom = offset;
  456.             baseRoom = nextCode.pc;
  457.             while (*nextCode.pc++)
  458.              offset++;
  459.             offset++;
  460.         } else if (strCmp(cmd, "#alldone") == SAMESTRING) {
  461.         break;
  462.         } else if (cmd[0] == '#') printf("? -- no '%s' command!\n", cmd);
  463.     }
  464.     }
  465.     if (nextCode.pc < &cfg.codeBuf[MAXCODE]) {
  466.        init(!(argc - 1));
  467.        wrapup();
  468.     } else {
  469.     illegal(
  470. "\7codeBuf[] overflow! Recompile with larger MAXCODE or reduce ctdlCnfg.sys\7"
  471.     );
  472.     }
  473. }
  474.  
  475. /***********************************************************************/
  476. /*    readString() reads a '#<id> "<value>"  since scanf can't         */
  477. /***********************************************************************/
  478. readString(source, destination)
  479. char *source, *destination;
  480. {
  481.     char string[80];
  482.     int  i, j;
  483.  
  484.     for (i = 0; source[i] != '"'; i++)
  485.         ;
  486.     for (j = 0, i++; source[i] != '"'; i++, j++)
  487.         string[j] = source[i];
  488.     string[j] = '\0';
  489.     strCpy(destination, string);
  490. }
  491.  
  492. /***********************************************************************/
  493. /*    illegal() Prints out configur error message and aborts           */
  494. /***********************************************************************/
  495. illegal(errorstring)
  496. char *errorstring;
  497. {
  498.     printf("\007\nERROR IN CONFIGURATION:\n%s\nABORTING", errorstring);
  499.     exit(7);
  500. }
  501.  
  502. /************************************************************************/
  503. /*    dGetWord() fetches one word from current message, off disk    */
  504. /*    returns TRUE if more words follow, else FALSE            */
  505. /************************************************************************/
  506. char dGetWord(dest, lim)
  507. char *dest;
  508. int  lim;
  509. {
  510.     char c;
  511.  
  512.     --lim;    /* play it safe */
  513.  
  514.     /* pick up any leading blanks: */
  515.     for (c = getMsgChar();   c == ' '  &&  c && lim;   c = getMsgChar()) {
  516.     if (lim) { *dest++ = c;   lim--; }
  517.     }
  518.  
  519.     /* step through word: */
  520.     for (         ;  c != ' ' && c && lim;   c = getMsgChar()) {
  521.     if (lim) { *dest++ = c;   lim--; }
  522.     }
  523.  
  524.     /* trailing blanks: */
  525.     for (         ;   c == ' ' && c && lim;   c = getMsgChar()) {
  526.     if (lim) { *dest++ = c;   lim--; }
  527.     }
  528.  
  529.     if (c)  unGetMsgChar(c);    /* took one too many    */
  530.  
  531.     *dest = '\0';        /* tie off string    */
  532.  
  533.     return  c;
  534. }
  535.  
  536. /************************************************************************/
  537. /*    getMessage() reads a message off disk into RAM.         */
  538. /*    a previous call to setUp has specified the message.        */
  539. /************************************************************************/
  540. getMessage()
  541. {
  542.     unsigned char c;
  543.  
  544.     /* clear msgBuf out */
  545.     msgBuf.mbauth[ 0]    = '\0';
  546.     msgBuf.mbdate[ 0]    = '\0';
  547.     msgBuf.mborig[ 0]    = '\0';
  548.     msgBuf.mboname[0]    = '\0';
  549.     msgBuf.mbroom[ 0]    = '\0';
  550.     msgBuf.mbsrcId[0]    = '\0';
  551.     msgBuf.mbtext[ 0]    = '\0';
  552.     msgBuf.mbto[   0]    = '\0';
  553.     msgBuf.mbaddr[ 0]    = '\0';
  554.  
  555.     do c = getMsgChar(); while (c != 0xFF);    /* find start of msg    */
  556.  
  557.     msgBuf.mbheadChar    = oldChar;        /* record location    */
  558.     msgBuf.mbheadSector = oldSector;
  559.  
  560.     getMsgStr(msgBuf.mbId, NAMESIZE);
  561.  
  562.     do    {
  563.     c = getMsgChar();
  564.     switch (c) {
  565.     case 'A':    getMsgStr(msgBuf.mbauth,  NAMESIZE);    break;
  566.     case 'D':    getMsgStr(msgBuf.mbdate,  NAMESIZE);    break;
  567.     case 'M':    /* just exit -- we'll read off disk */    break;
  568.     case 'N':    getMsgStr(msgBuf.mboname, NAMESIZE);    break;
  569.     case 'O':    getMsgStr(msgBuf.mborig,  NAMESIZE);    break;
  570.     case 'R':    getMsgStr(msgBuf.mbroom,  NAMESIZE);    break;
  571.     case 'S':    getMsgStr(msgBuf.mbsrcId, NAMESIZE);    break;
  572.     case 'T':    getMsgStr(msgBuf.mbto,      NAMESIZE);    break;
  573.     case 'Q':    getMsgStr(msgBuf.mbaddr,  NAMESIZE);    break;
  574.     default:
  575.         getMsgStr(msgBuf.mbtext, MAXTEXT);    /* discard unknown field  */
  576.         msgBuf.mbtext[0]    = '\0';
  577.         break;
  578.     }
  579.     } while (c != 'M'  &&  isAlpha(c));
  580.     if (strCmpU(msgBuf.mbroom, "Mail") == SAMESTRING) mailCount++;
  581. }
  582.  
  583. /************************************************************************/
  584. /*    getMsgChar() returns sequential chars from message on disk    */
  585. /************************************************************************/
  586. unsigned char getMsgChar()
  587. {
  588.     char toReturn;
  589.  
  590.     if (GMCCache) {    /* someone did an unGetMsgChar() --return it    */
  591.     toReturn= GMCCache;
  592.     GMCCache= '\0';
  593.     return toReturn;
  594.     }
  595.  
  596.     oldChar    = thisChar;
  597.     oldSector    = thisSector;
  598.  
  599.     toReturn    = sectBuf[thisChar];
  600.  
  601. #ifdef XYZZY
  602.     if (debug) putCh(visible(toReturn));
  603. #endif
  604.  
  605.     thisChar    = ++thisChar % SECTSIZE;
  606.     if (thisChar == 0) {
  607.     /* time to read next sector in: */
  608.     thisSector  = ++thisSector % cfg.maxMSector;
  609.     fseek(msgfl, (long) thisSector * SECTSIZE, 0);
  610.     if (fread(sectBuf, SECTSIZE, 1, msgfl) != 1) {
  611.         exit(printf("?nextMsgChar-read fail"));
  612.     }
  613.     crypte(sectBuf, SECTSIZE, 0);
  614.     }
  615.     return(toReturn);
  616. }
  617.  
  618. /************************************************************************/
  619. /*    getMsgStr() reads a string from message.buf            */
  620. /************************************************************************/
  621. getMsgStr(dest, lim)
  622. char *dest;
  623. int  lim;
  624. {
  625.     char c;
  626.  
  627.     while (c = getMsgChar()) {        /* read the complete string    */
  628.     if (lim) {            /* if we have room then     */
  629.         lim--;
  630.         *dest++ = c;        /* copy char to buffer        */
  631.     }
  632.     }
  633.     *dest = '\0';            /* tie string off with null    */
  634. }
  635.  
  636. /************************************************************************/
  637. /*    msgInit() sets up lowId, highId, cfg.catSector and cfg.catChar, */
  638. /*    by scanning over message.buf                    */
  639. /************************************************************************/
  640. msgInit()
  641. {
  642.     int   atoi();
  643.     ulong first, here;
  644.  
  645.     startAt(0, 0);
  646.     getMessage();
  647.  
  648.     /* get the ID# */
  649.     sscanf(msgBuf.mbId, "%ld", &first);
  650.     printf("message# %lu\n", first);
  651.  
  652.     cfg.newest = cfg.oldest = first;
  653.  
  654.     cfg.catSector   = thisSector;
  655.     cfg.catChar     = thisChar;
  656.  
  657.     for (getMessage();
  658.          sscanf(msgBuf.mbId, "%ld", &here), here != first;
  659.               getMessage()) {
  660.     printf("message# %lu\n", here);
  661.  
  662.     /* find highest and lowest message IDs: */
  663.     if (here < cfg.oldest) {
  664.         cfg.oldest = here;
  665.         printf(" oldest=%lu\n", cfg.oldest);
  666.     }
  667.     if (here > cfg.newest) {
  668.         cfg.newest = here;
  669.         printf(" newest=%lu\n", cfg.newest);
  670.  
  671.         /* read rest of message in and remember where it ends,    */
  672.         /* in case it turns out to be the last message        */
  673.         /* in which case, that's where to start writing next message*/
  674.         while (dGetWord(msgBuf.mbtext, MAXTEXT));
  675.         cfg.catSector   = thisSector;
  676.         cfg.catChar     = thisChar;
  677.     }
  678.     }
  679. }
  680.  
  681. /************************************************************************/
  682. /*    startAt() sets location to begin reading message from        */
  683. /************************************************************************/
  684. startAt(sect, byt)
  685. unsigned sect;
  686. int   byt;
  687. {
  688.     GMCCache  = '\0';    /* cache to unGetMsgChar() into */
  689.  
  690.     if (sect >= cfg.maxMSector) {
  691.     printf("?startAt s=%d,b=%d", sect, byt);
  692.     printf("?startAt crash");
  693.     exit();
  694.     }
  695.     thisChar    = byt;
  696.     thisSector    = sect;
  697.  
  698.     fseek(msgfl, SECTSIZE * sect, 0);
  699.     if (fread(sectBuf, SECTSIZE, 1, msgfl) != 1) {
  700.     printf("?startAt read fail");
  701.     }
  702.     crypte(sectBuf, SECTSIZE, 0);
  703. }
  704.  
  705. /************************************************************************/
  706. /*    unGetMsgChar() returns (at most one) char to getMsgChar()    */
  707. /************************************************************************/
  708. unGetMsgChar(c)
  709. unsigned char c;
  710. {
  711.     GMCCache    = c;
  712. }
  713.  
  714. /************************************************************************/
  715. /*    zapMsgFl() initializes message.buf                */
  716. /************************************************************************/
  717. zapMsgFile()
  718. {
  719.     label fn;
  720.  
  721.     printf("\nDestroy all current messages? ");
  722.     if (toUpper(getch()) != 'Y')   return FALSE;
  723.  
  724.     if (cfg.mirror) printf("Creating primary message file.\n");
  725.     realZap();
  726.     if (cfg.mirror) {
  727.     fclose(msgfl);
  728.     strCpy(fn, "a:ctdlmsg.sys");
  729.     fn[0] += cfg.mbkpDisk;
  730.     if ((msgfl = fopen(fn, "wrb")) == NULL)
  731.         illegal("?Can't create the secondary message file!");
  732.     printf("Creating secondary message file.\n");
  733.     realZap();
  734.     }
  735.     return TRUE;
  736. }
  737.  
  738. /************************************************************************/
  739. /*    realZap() does work of zapMsgFile                */
  740. /************************************************************************/
  741. realZap()
  742. {
  743.     int   i;
  744.     unsigned sect;
  745.  
  746.     /* put null message in first sector... */
  747.     sectBuf[0]    = 0xFF; /*   \                      */
  748.     sectBuf[1]    =  '1'; /*    >  Message ID "1" MS-DOS style  */
  749.     sectBuf[2]    = '\0'; /*   /                      */
  750.     sectBuf[3]    =  'M'; /*   \      Null messsage           */
  751.     sectBuf[4]    = '\0'; /*   /                      */
  752.  
  753.     cfg.newest = cfg.oldest = 1l;
  754.  
  755.     cfg.catSector   = 0;
  756.     cfg.catChar     = 5;
  757.  
  758.     for (i=5;  i<SECTSIZE;  i++) sectBuf[i] = 0;
  759.  
  760.     crypte(sectBuf, SECTSIZE, 0);    /* encrypt    */
  761.     if (fwrite(sectBuf, SECTSIZE, 1, msgfl) != 1) {
  762.     printf("zapMsgFil: write failed\n");
  763.     }
  764.  
  765.     crypte(sectBuf, SECTSIZE, 0);    /* decrypt    */
  766.     sectBuf[0] = 0;
  767.     crypte(sectBuf, SECTSIZE, 0);    /* encrypt    */
  768.     printf("\n%d sectors to be cleared\n", cfg.maxMSector);
  769.     for (sect = 1l;  sect < cfg.maxMSector;  sect++) {
  770.     printf("%u\r", sect);
  771.     if (fwrite(sectBuf, SECTSIZE, 1, msgfl) != 1) {
  772.         printf("zapMsgFil: write failed\n");
  773.     }
  774.     }
  775.     crypte(sectBuf, SECTSIZE, 0);    /* decrypt    */
  776.     return TRUE;
  777. }
  778.  
  779. /************************************************************************/
  780. /*    indexRooms() -- build RAM index to CTDLROOM.SYS, displays stats.*/
  781. /************************************************************************/
  782. indexRooms()
  783. {
  784.     int  goodRoom, m, roomCount, slot;
  785.  
  786.     roomCount = 0;
  787.     for (slot = 0;  slot < MAXROOMS;  slot++) {
  788.     getRoom(slot);
  789.     printf("Checking room #%d: ", slot);
  790.     if (roomBuf.rbflags.INUSE == 1) {
  791.         roomBuf.rbflags.INUSE = 0;        /* clear "inUse" flag */
  792.         for (m = 0, goodRoom = FALSE; m < MSGSPERRM && !goodRoom; m++) {
  793.         if (roomBuf.msg[m].rbmsgNo > cfg.oldest) {
  794.             goodRoom    = TRUE;
  795.         }
  796.         }
  797.         if (goodRoom   || roomBuf.rbflags.PERMROOM == 1)   {
  798.         roomBuf.rbflags.INUSE = 1;
  799.         }
  800.  
  801.         if (roomBuf.rbflags.INUSE == 1) {
  802.         if (slot == 0)               /* Ugly kludge */
  803.             strCpy(roomBuf.rbname, baseRoom);
  804.         roomCount++;
  805.         }
  806.         else {
  807.         roomBuf.rbflags.INUSE     = 0;
  808.         roomBuf.rbflags.MSDOSDIR = 0;
  809.         roomBuf.rbflags.PERMROOM = 0;
  810.         roomBuf.rbflags.INUSE     = 0;
  811.         }
  812.     }
  813.     printf("%s\n",
  814.            (roomBuf.rbflags.INUSE == 1) ? roomBuf.rbname : "<not in use>");
  815.     noteRoom();
  816.     putRoom(slot);
  817.     }
  818.     printf(" %d of %d rooms in use\n", roomCount, MAXROOMS);
  819. }
  820.  
  821. /************************************************************************/
  822. /*    noteRoom() -- enter room into RAM index array.            */
  823. /************************************************************************/
  824. noteRoom()
  825. {
  826.     int   i;
  827.     ulong last;
  828.  
  829.     last = 0l;
  830.     for (i = 0;  i < MSGSPERROOM;  i++)  {
  831.     if (roomBuf.msg[i].rbmsgNo > cfg.newest) {
  832.         roomBuf.msg[i].rbmsgNo = 0l;
  833.     }
  834.     if (roomBuf.msg[i].rbmsgNo > last) {
  835.         last = roomBuf.msg[i].rbmsgNo;
  836.     }
  837.     }
  838.     roomTab[thisRoom].rtlastMessage = last         ;
  839.     strCpy(roomTab[thisRoom].rtname, roomBuf.rbname) ;
  840.     roomTab[thisRoom].rtgen           = roomBuf.rbgen    ;
  841.     roomTab[thisRoom].rtflags.INUSE    = roomBuf.rbflags.INUSE;
  842.     roomTab[thisRoom].rtflags.PUBLIC   = roomBuf.rbflags.PUBLIC;
  843.     roomTab[thisRoom].rtflags.MSDOSDIR = roomBuf.rbflags.MSDOSDIR;
  844.     roomTab[thisRoom].rtflags.PERMROOM = roomBuf.rbflags.PERMROOM;
  845.     roomTab[thisRoom].rtflags.SKIP     = roomBuf.rbflags.SKIP;
  846. }
  847.  
  848. /************************************************************************/
  849. /*    zapRoomFile() erases and re-initailizes CTDLROOM.SYS        */
  850. /************************************************************************/
  851. zapRoomFile()
  852. {
  853.     int i;
  854.  
  855.     printf("\nWipe room file? ");
  856.     if (toUpper(getch()) != 'Y') return FALSE;
  857.     printf("\n");
  858.  
  859.     roomBuf.rbflags.INUSE    = FALSE;
  860.     roomBuf.rbflags.PUBLIC   = FALSE;
  861.     roomBuf.rbflags.MSDOSDIR = FALSE;
  862.     roomBuf.rbflags.PERMROOM = FALSE;
  863.     roomBuf.rbflags.SKIP     = FALSE;
  864.     roomBuf.rbgen         = 0;
  865.     roomBuf.rbdisk         = 0;
  866.     roomBuf.rbdirname[0]     = 0;
  867.     roomBuf.rbname[0]         = 0;   /* unnecessary -- but I like it...    */
  868.     for (i = 0;  i < MSGSPERRM;  i++) {
  869.     roomBuf.msg[i].rbmsgNo =  0l;
  870.     roomBuf.msg[i].rbmsgLoc = 0 ;
  871.     }
  872.  
  873.     printf("maxrooms=%d\n", MAXROOMS);
  874.  
  875.     for (i = 0;  i < MAXROOMS;    i++) {
  876.     printf("clearing room %d\n", i);
  877.     putRoom(i);
  878.     noteRoom();
  879.     }
  880.  
  881.     /* Lobby> always exists -- guarantees us a place to stand! */
  882.     thisRoom        = 0        ;
  883.     strCpy(roomBuf.rbname, baseRoom)    ;
  884.     roomBuf.rbflags.PERMROOM = TRUE;
  885.     roomBuf.rbflags.PUBLIC   = TRUE;
  886.     roomBuf.rbflags.INUSE    = TRUE;
  887.  
  888.     putRoom(LOBBY);
  889.     noteRoom();
  890.  
  891.     /* Mail> is also permanent...    */
  892.     thisRoom        = MAILROOM    ;
  893.     strCpy(roomBuf.rbname, "Mail")    ;
  894.     /* Don't bother to copy flags, they remain the same (right?)    */
  895.     putRoom(MAILROOM);
  896.     noteRoom();
  897.  
  898.     /* Aide> also...            */
  899.     thisRoom        = AIDEROOM    ;
  900.     strCpy(roomBuf.rbname, "Aide")    ;
  901.     roomBuf.rbflags.PERMROOM = TRUE;
  902.     roomBuf.rbflags.PUBLIC   = FALSE;
  903.     roomBuf.rbflags.INUSE    = TRUE;
  904.     putRoom(AIDEROOM);
  905.     noteRoom();
  906.  
  907.     return TRUE;
  908. }
  909.  
  910. /************************************************************************/
  911. /*    setSpace() moves us to a disk and user#             */
  912. /************************************************************************/
  913. #define SETDISK     14
  914. setSpace(disk, dir)
  915. char disk;
  916. char *dir;
  917. {
  918.     bdos(SETDISK, disk);
  919.     cfg.ourDisk     = disk;
  920.  
  921.     if (strCmp(dir, "") == SAMESTRING) {
  922.     strCpy(cfg.ourUser, "..");
  923.     }
  924.     else {
  925.     strCpy(cfg.ourUser, dir);
  926.     if (chdir(dir) == EOF) {
  927.         printf("?Directory not present!\n ");
  928.         setSpace(cfg.homeDisk, "");
  929.         return FALSE;
  930.     }
  931.     }
  932.     return TRUE;
  933. }
  934.  
  935. /************************************************************************/
  936. /*    hash() hashes a string to an integer                */
  937. /************************************************************************/
  938. int hash(str)
  939. char *str;
  940. {
  941.     int  h, i, shift;
  942.  
  943.     for (h=shift=0;  *str;  shift=(shift+1)&7, str++) {
  944.     h ^= (i=toUpper(*str)) << shift;
  945.     }
  946.     return h;
  947. }
  948.  
  949. /************************************************************************/
  950. /*    logInit() indexes ctdllog.sys                    */
  951. /************************************************************************/
  952. logInit()
  953. {
  954.     int i;
  955.     int logSort();
  956.     int count = 0;
  957.     long rewind();
  958.  
  959.     if (rewind(logfl) != 0l) illegal("Rewinding logfl failed!");
  960.     /* clear logTab */
  961.     for (i = 0; i < cfg.MAXLOGTAB; i++) logTab[i].ltnewest = 0l;
  962.  
  963.     /* load logTab: */
  964.     for (thisLog = 0;  thisLog < cfg.MAXLOGTAB;  thisLog++) {
  965.     printf("log#%3d", thisLog);
  966.     getLog(&logBuf, thisLog);
  967.  
  968.     /* count valid entries:         */
  969.     if (logBuf.lbflags.L_INUSE == 1) {
  970.         count++;
  971.         printf("   %s", logBuf.lbname);
  972.     }
  973.     else printf("    <not in use>");
  974.     printf("\n");
  975.  
  976.     /* copy relevant info into index:   */
  977.     logTab[thisLog].ltnewest = logBuf.lbvisit[0];
  978.     logTab[thisLog].ltlogSlot= thisLog;
  979.     if (logBuf.lbflags.L_INUSE == 1) {
  980.         logTab[thisLog].ltnmhash = hash(logBuf.lbname);
  981.         logTab[thisLog].ltpwhash = hash(logBuf.lbpw  );
  982.     }
  983.     else {
  984.         logTab[thisLog].ltnmhash = 0;
  985.         logTab[thisLog].ltpwhash = 0;
  986.     }
  987.     }
  988.     printf(" logInit--%d valid log entries\n", count);
  989.     printf("sortLog...\n");
  990.     qsort(logTab, cfg.MAXLOGTAB, cfg.sizeLTentry, logSort);
  991. }
  992.  
  993. /************************************************************************/
  994. /*    logSort() Sorts 2 entries in logTab                */
  995. /************************************************************************/
  996. int logSort(s1, s2)
  997. struct lTable *s1, *s2;
  998. {
  999.     if (s1->ltnmhash == 0 && s2->ltnmhash == 0)
  1000.     return 0;
  1001.     if (s1->ltnmhash == 0 && s2->ltnmhash != 0)
  1002.     return 1;
  1003.     if (s1->ltnmhash != 0 && s2->ltnmhash == 0)
  1004.     return -1;
  1005.     if (s1->ltnewest < s2->ltnewest)
  1006.     return 1;
  1007.     if (s1->ltnewest > s2->ltnewest)
  1008.     return -1;
  1009.     return 0;
  1010. }
  1011.  
  1012. /************************************************************************/
  1013. /*    noteLog() notes logTab entry in RAM buffer in master index    */
  1014. /************************************************************************/
  1015. noteLog()
  1016. {
  1017.     int i, slot;
  1018.  
  1019.     /* figure out who it belongs between:    */
  1020.     for (i = 0;  logTab[i].ltnewest > logBuf.lbvisit[0];  i++);
  1021.  
  1022.     /* note location and open it up:        */
  1023.     slot = i;
  1024.     slideLTab(slot, cfg.MAXLOGTAB-1);
  1025.  
  1026.     /* insert new record */
  1027.     logTab[slot].ltnewest    = logBuf.lbvisit[0]  ;
  1028.     logTab[slot].ltlogSlot    = thisLog         ;
  1029.     logTab[slot].ltpwhash    = hash(logBuf.lbpw)  ;
  1030.     logTab[slot].ltnmhash    = hash(logBuf.lbname);
  1031. }
  1032.  
  1033. /************************************************************************/
  1034. /*    slideLTab() slides bottom N lots in logTab down.  For sorting.    */
  1035. /************************************************************************/
  1036. slideLTab(slot, last)
  1037. int slot;
  1038. int last;
  1039. {
  1040.     int i;
  1041.  
  1042.     /* open slot up: (movmem isn't guaranteed on overlaps) */
  1043.     for (i = last - 1;    i >= slot;  i--)  {
  1044.     movmem(&logTab[i], &logTab[i + 1], cfg.sizeLTentry);
  1045.     }
  1046. }
  1047.  
  1048. /************************************************************************/
  1049. /*    wrapup() finishes up and writes ctdlTabl.sys out, finally    */
  1050. /************************************************************************/
  1051. wrapup()
  1052. {
  1053.     printf("\ncreating ctdlTabl.sys table\n");
  1054.     if (!msgZap)  msgInit();
  1055.     if (!roomZap) indexRooms();
  1056.     cfg.weAre = CITADEL;
  1057.     if (!logZap)  logInit();
  1058.     netInit();
  1059.     fclose(netfl);
  1060.     fclose(roomfl);
  1061.     fclose(msgfl);
  1062.     fclose(logfl);
  1063.     printf("%ld of the messages were Mail\n", mailCount);
  1064.     printf("writeSysTab = %d\n", writeSysTab());
  1065. }
  1066.  
  1067. /************************************************************************/
  1068. /*    zapLogFile() erases & re-initializes userlog.buf        */
  1069. /************************************************************************/
  1070. zapLogFile()
  1071. {
  1072.     int  i;
  1073.  
  1074.     printf("\nWipe out log file? ");
  1075.     if (toUpper(getch()) != 'Y')   return FALSE;
  1076.     printf("\n");
  1077.  
  1078.     /* clear RAM buffer out:            */
  1079.     logBuf.lbflags.L_INUSE = FALSE;
  1080.     for (i = 0;  i < MAILSLOTS;  i++) {
  1081.     logBuf.lbslot[i] = 0l;
  1082.     logBuf.lbId[i]     = 0l;
  1083.     }
  1084.     for (i = 0;  i < NAMESIZE;    i++) {
  1085.     logBuf.lbname[i] = 0;
  1086.     logBuf.lbpw[i]     = 0;
  1087.     }
  1088.  
  1089.     /* write empty buffer all over file;    */
  1090.     for (i = 0; i < cfg.MAXLOGTAB;  i++) {
  1091.     printf("Clearing log #%d\n", i);
  1092.     putLog(&logBuf, i);
  1093.     logTab[i].ltnewest = logBuf.lbvisit[0];
  1094.     logTab[i].ltlogSlot= i;
  1095.     logTab[i].ltnmhash = hash(logBuf.lbname);
  1096.     logTab[i].ltpwhash = hash(logBuf.lbpw  );
  1097.     }
  1098.     return TRUE;
  1099. }
  1100.  
  1101. getch()
  1102. {
  1103.     return bdos(7);
  1104. }
  1105.  
  1106. /************************************************************************/
  1107. /*    netInit() Initialize RAM index for net                */
  1108. /************************************************************************/
  1109. netInit()
  1110. {
  1111.     label temp;
  1112.     int i = 0;
  1113.  
  1114.     cfg.netSize = (int) ((fseek(netfl, -1l, 2) + 1) / sizeof (netBuf));
  1115.     netTab    = (struct netTable *) malloc(sizeof (*netTab) * cfg.netSize);
  1116.     while (i < cfg.netSize) {
  1117.     getNet(i);
  1118.     normId(netBuf.netId, temp);
  1119.     netTab[i].ntnmhash = hash(netBuf.netName);
  1120.     netTab[i].ntidhash = hash(temp);
  1121.     netTab[i].ntflags.in_use = netBuf.nbflags.in_use;
  1122.     netTab[i].ntflags.normal_mail = netBuf.nbflags.normal_mail;
  1123.     netTab[i].ntflags.room_files  = netBuf.nbflags.room_files;
  1124.     printf("System %3d. %s\n", i,
  1125.        (netBuf.nbflags.in_use) ? netBuf.netName : "<not in use>");
  1126.     i++;
  1127.     }
  1128. }
  1129.  
  1130. /************************************************************************/
  1131. /*    strCmpU() is strcmp(), but ignoring case distinctions        */
  1132. /************************************************************************/
  1133. int strCmpU(s, t)
  1134. char s[], t[];
  1135. {
  1136.     int  i;
  1137.  
  1138.     i = 0;
  1139.  
  1140.     while (toUpper(s[i]) == toUpper(t[i])) {
  1141.     if (s[i++] == '\0')  return 0;
  1142.     }
  1143.     return  toUpper(s[i]) - toUpper(t[i]);
  1144. }
  1145.  
  1146. /************************************************************************/
  1147. /*    normId() Normalizes a node id.                    */
  1148. /************************************************************************/
  1149. normId(source, dest)
  1150. label source, dest;
  1151. {
  1152.     while (!isalpha(*source) && *source)
  1153.     source++;
  1154.     if (!*source) return FALSE;
  1155.     *dest++ = toUpper(*source++);
  1156.     while (!isalpha(*source) && *source)
  1157.     source++;
  1158.     if (!*source) return FALSE;
  1159.     *dest++ = toUpper(*source++);
  1160.     while (*source) {
  1161.     if (isdigit(*source))
  1162.         *dest++ = *source;
  1163.     source++;
  1164.     }
  1165.     *dest = '\0';
  1166.     return TRUE;
  1167. }
  1168.  
  1169. /************************************************************************/
  1170. /*    crashout() fatal error, for library functions            */
  1171. /************************************************************************/
  1172. crashout(str)
  1173. char *str;
  1174. {
  1175.     illegal(str);
  1176. }
  1177.